<template>
  <div id="root">
    <header>
      <h1>GAME-2048</h1>
      <a id="new_game_button" @click="newGame()">New Game</a>
      <transition name='list' tag="div">
        <p>score: <span>{{score}}</span></p>
      </transition>
    </header>
    <div style="text-align: center;"><label>{{message}}</label></div>
    <div class="grid_container" :style="gridContainerCss">

      <div v-for="(cells, index) in board1 " :key="index+'grid'">
        <div class="grid_cell" v-for="(cell, index2) in cells" :key="index2"
             :style="getNumberStyle(index, index2)">
        </div>
      </div>

      <div v-for="(cells, index) in board1" :key="index + 'cell'" class="list-complete-item">
        <transition-group name="list" tag="div">
          <div v-for="(cell, index2) in cells" v-if="cell > 0" :key="index + ' ' + index2"
               class="number_cell" :style="getNumberStyle(index, index2)">{{cell}}
          </div>
        </transition-group>
      </div>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'

export default {
  name: 'game',
  data () {
    return {
      board1: [],
      gridContainerWidth: 500,
      cellSize: 100,
      cellSpace: 20,
      gridContainerCss: {},
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0,
      name: '',
      socket: null,
      message: '',
      otherScore: 0,
      showScore: false
    }
  },
  computed: {
    score: function () {
      let s = 0
      for (let i = 0; i < this.board1.length; i++) {
        for (let j = 0; j < this.board1[i].length; j++) {
          s += this.board1[i][j]
        }
      }

      return s
    }
  },

  created () {
    for (let i = 0; i < 4; i++) {
      this.board1[i] = []
      for (let j = 0; j < 4; j++) {
        this.board1[i][j] = 0
      }
    }
    let documentWidth = window.screen.width

    if (documentWidth < 765) {
      this.gridContainerWidth = documentWidth
      this.cellSize = 0.18 * documentWidth
      this.cellSpace = 0.04 * documentWidth
    }
    this.gridContainerCss = {
      'width': this.gridContainerWidth - 2 * this.cellSpace + 'px',
      'height': this.gridContainerWidth - 2 * this.cellSpace + 'px',
      'padding': this.cellSpace + 'px',
      'border-radius': 0.02 * this.gridContainerWidth + 'px'
    }

    this.newGame()
    let that = this
    document.addEventListener('touchmove', function (event) {
      event.preventDefault()
    }, {passive: false})
    document.addEventListener('touchstart', function (event) {
      that.startX = event.changedTouches[0].pageX
      that.startY = event.changedTouches[0].pageY
    })
    document.addEventListener('touchend', function (event) {
      that.endX = event.changedTouches[0].pageX
      that.endY = event.changedTouches[0].pageY

      let deltaX = that.endX - that.startX
      let deltaY = that.endY - that.startY
      let absX = Math.abs(deltaX)
      let absY = Math.abs(deltaY)
      if (absX < 0.1 * window.screen.availWidth && absY < 0.1 * window.screen.availWidth) {
        return
      }

      if (absX >= absY) {
        if (deltaX > 0) {
          that.moveRight()
        } else {
          that.moveLeft()
        }
      } else {
        if (deltaY > 0) {
          that.moveDown()
        } else {
          that.moveUp()
        }
      }
    })
  },
  methods: {
    send: function send (type, message) {
      let content = type + 'typeAndContent' + message
      this.socket.send(content)
    },

    join: function () {
      if (this.name.length === 0) {
        alert('请输入你的大名')
      } else {
        this.send('join', this.name)
      }
    },
    showMessage: function (message) {
      this.message = message
    },
    updateScore: function (data) {
      this.otherScore = data
    },
    newGame: function () {
      console.log('new game')
      let tempBoard = []
      for (let i = 0; i < 4; i++) {
        tempBoard[i] = []
        for (let j = 0; j < 4; j++) {
          tempBoard[i][j] = 0
        }
      }
      this.board1 = tempBoard
      this.generate_one_number()
      this.generate_one_number()
    },
    getNumberStyle: function (index, index2) {
      let style = {
        'top': this.cellSpace + index * (this.cellSpace + this.cellSize) + 'px',
        'left': this.cellSpace + index2 * (this.cellSpace + this.cellSize) + 'px',
        'line-height': this.cellSize + 'px',
        'font-size': 0.8 * this.cellSize + 'px',
        'width': this.cellSize + 'px',
        'height': this.cellSize + 'px'

      }
      let cellValue = this.board1[index][index2]
      if (cellValue !== 0) {
        style['background-color'] = this.getBackgroundColor(this.board1[index][index2])
      }
      if (cellValue > 999) {
        style['font-size'] = 0.42 * this.cellSize + 'px'
      } else if (cellValue > 99) {
        style['font-size'] = 0.5 * this.cellSize + 'px'
      } else if (cellValue > 9) {
        style['font-size'] = 0.65 * this.cellSize + 'px'
      }
      return style
    },
    generate_one_number: function generateOneNumber () {
      if (this.nospace(this.board1)) {
        alert('GAME OVER')
        return false
      }
      // 随机一个位置
      let randx = Math.floor(Math.random() * 4)
      let randy = Math.floor(Math.random() * 4)

      while (true) {
        if (this.board1[randx][randy] === 0) {
          break
        }
        randx = Math.floor(Math.random() * 4)
        randy = Math.floor(Math.random() * 4)
      }

      // 在随机位置显示随机数字
      this.board1[randx][randy] = Math.random() < 0.5 ? 2 : 4
      let tempRow = this.board1[randx]
      Vue.set(this.board1, randx, tempRow)
      return true
    },
    nospace: function nospace (board) {
      for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
          if (board[i][j] === 0) {
            return false
          }
        }
      }
      return true
    },

    can_move_left: function canMoveLeft (board) {
      for (let i = 0; i < 4; i++) {
        for (let j = 1; j < 4; j++) {
          if (board[i][j] !== 0) {
            if (board[i][j - 1] === 0 || board[i][j] === board[i][j - 1]) {
              return true
            }
          }
        }
      }
      return false
    },

    can_move_right: function canMoveRight (board) {
      for (let i = 0; i < 4; i++) {
        for (let j = 2; j >= 0; j--) {
          if (board[i][j] !== 0) {
            if (board[i][j + 1] === 0 || board[i][j] === board[i][j + 1]) {
              return true
            }
          }
        }
      }
      return false
    },

    can_move_up: function canMoveUp (board) {
      for (let j = 0; j < 4; j++) {
        for (let i = 1; i < 4; i++) {
          if (board[i][j] !== 0) {
            if (board[i - 1][j] === 0 || board[i - 1][j] === board[i][j]) {
              return true
            }
          }
        }
      }
      return false
    },

    can_move_down: function canMoveDown (board) {
      for (let j = 0; j < 4; j++) {
        for (let i = 2; i >= 0; i--) {
          if (board[i][j] !== 0) {
            if (board[i + 1][j] === 0 || board[i + 1][j] === board[i][j]) {
              return true
            }
          }
        }
      }
      return false
    },
    nomove: function nomove (board) {
      return !(this.can_move_down(board) || this.can_move_up(board) || this.can_move_right(board) || this.can_move_left(board))
    },
    getBackgroundColor: function (number) {
      if (number === 2) {
        return '#eee4da'
      } else if (number === 4) {
        return '#ede0c8'
      } else if (number === 8) {
        return '#f2b179'
      } else if (number === 16) {
        return '#f59563'
      } else if (number === 32) {
        return '#f67c5f'
      } else if (number === 64) {
        return '#f65e3b'
      } else if (number === 128) {
        return '#edcf72'
      } else if (number === 256) {
        return '#edcc61'
      } else if (number === 512) {
        return '#9c0'
      } else if (number === 1024) {
        return '#33b5e5'
      } else if (number === 2048) {
        return '#09c'
      } else if (number === 4096) {
        return '#a6c'
      } else if (number === 8192) {
        return '#93c'
      }
      return 'black'
    },
    no_block_horizontal: function noBlockHorizontal (row, col1, col2, board) {
      for (let i = col1 + 1; i < col2; i++) {
        if (board[row][i] !== 0) {
          return false
        }
      }
      return true
    },

    no_block_vertical: function noBlockVertical (col, row1, row2, board) {
      for (let i = row1 + 1; i < row2; i++) {
        if (board[i][col] !== 0) {
          return false
        }
      }
      return true
    },
    moveLeft: function moveLeft () {
      if (!this.can_move_left(this.board1)) {
        return false
      }
      let board = this.board1
      for (let i = 0; i < 4; i++) {
        for (let j = 1; j < 4; j++) {
          if (board[i][j] !== 0) {
            for (let k = 0; k < j; k++) {
              if (board[i][k] === 0 && this.no_block_horizontal(i, k, j, board)) {
                board[i][k] = board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              } else if (board[i][k] === board[i][j] &&
                  this.no_block_horizontal(i, k, j, board)) {
                board[i][k] += board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              }
            }
          }
        }
      }
      this.board1 = board
      this.generate_one_number()
    },

    moveRight: function moveRight () {
      if (!this.can_move_right(this.board1)) {
        return false
      }
      let board = this.board1
      for (let i = 0; i < 4; i++) {
        for (let j = 2; j >= 0; j--) {
          if (board[i][j] !== 0) {
            for (let k = 3; k > j; k--) {
              if (board[i][k] === 0 && this.no_block_horizontal(i, j, k, board)) {
                board[i][k] = board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              } else if (board[i][k] === board[i][j] &&
                  this.no_block_horizontal(i, j, k, board)) {
                board[i][k] += board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              }
            }
          }
        }
      }
      this.board1 = board
      this.generate_one_number()
    },

    moveUp: function moveUp () {
      if (!this.can_move_up(this.board1)) {
        return false
      }
      let board = this.board1
      for (let j = 0; j < 4; j++) {
        for (let i = 1; i < 4; i++) {
          if (board[i][j] !== 0) {
            for (let k = 0; k < i; k++) {
              if (board[k][j] === 0 && this.no_block_vertical(j, k, i, board)) {
                board[k][j] = board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              } else if (board[k][j] === board[i][j] &&
                  this.no_block_vertical(j, k, i, board)) {
                board[k][j] += board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              }
            }
          }
        }
      }
      this.board1 = board
      this.generate_one_number()
    },

    moveDown: function moveDown () {
      if (!this.can_move_down(this.board1)) {
        return false
      }
      // move down
      let board = this.board1
      for (let j = 0; j < 4; j++) {
        for (let i = 2; i >= 0; i--) {
          if (board[i][j] !== 0) {
            for (let k = 3; k > i; k--) {
              if (board[k][j] === 0 && this.no_block_vertical(j, i, k, board)) {
                board[k][j] = board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              } else if (board[k][j] === board[i][j] &&
                  this.no_block_vertical(j, i, k, board)) {
                board[k][j] += board[i][j]
                board[i][j] = 0
                this.board1 = board
                break
              }
            }
          }
        }
      }
      this.board1 = board
      this.generate_one_number()
    }
  }
}

</script>

<style scoped>
  header {
    display: block;
    margin: 0 auto;
    width: 100%;
    text-align: center;
  }

  header h1 {
    font-family: Arial, serif;
    font-size: 40px;
    font-weight: bold;
    margin: 0 auto;
  }

  header #new_game_button {
    margin: 0 auto;
    width: 100px;
    padding: 10px 10px;
    background-color: #8f7a66;
    font-family: Arial, serif;
    color: white;
    border-radius: 10px;
    text-decoration: none;
  }

  header #new_game_button:hover {
    background-color: #9f8b77;
  }

  header p {
    font-family: Arial, serif;
    font-size: 25px;
    margin: 5px auto;
  }

  .grid_container {
    width: 100%;
    height: 40%;
    padding: 20px;
    margin: auto;
    background-color: #bbada0;
    border-radius: 10px;
    position: relative;
  }

  .grid_cell {
    width: 18%;
    height: 18%;
    border-radius: 6px;
    background-color: #ccc0b3;
    position: absolute;
  }

  .number_cell {
    border-radius: 6px;
    font-family: Arial, serif;
    font-weight: bold;
    text-align: center;
    position: absolute;
  }

  .list-item {
    display: inline-block;
    margin-right: 10px;
  }

  .list-enter-active, .list-leave-active {
    transition: all 1s;
  }

  .list-enter, .list-leave-to {
    opacity: 0;
    transform: scale(1, 1);
  }

</style>
